<?php
/**
 * Created by PhpStorm.
 * User: eugene
 * Date: 2018/4/23
 * Time: 16:06
 */

namespace App\Http\Controllers;


use App\Models\Member;
use App\Models\Merchant\Gift;
use App\Models\Merchant\GiftLog;
use App\Repos\MemberRepo;
use App\Repos\MerchantRepo;
use App\Transformers\GiftLogTransformer;
use App\Transformers\GiftTransformer;
use App\Transformers\MemberTransformer;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class MerchantController extends ApiController
{
    protected $giftTransformer;
    private $config;

    public function __construct(GiftTransformer $giftTransformer)
    {
        parent::__construct();
        $this->giftTransformer = $giftTransformer;
        $this->config = config('car.merchant_config');
    }

    public function index()
    {
        $current_hour = date('G');
        if ($current_hour < $this->config['begin_hour'])
            return $this->error(1, '今日未开始');
        if ($current_hour > $this->config['end_hour'])
            return $this->error(1, '今日已结束');

        $memberTransformer = new MemberTransformer();
        $userInfo = $memberTransformer->singleData($this->user);

        $today_lottery_times = GiftLog::where('user_id', $this->user->id)
            ->where('created_at', '>', Carbon::today()->toDateTimeString())
            ->count();

        $timesInfo = [
            'today_surplus' => $today_lottery_times < $this->config['day_limit']
                ? $this->config['day_limit'] - $today_lottery_times
                : 0,
            'today_limit' => $this->config['day_limit'],
        ];

        $gifts = $this->giftTransformer->listData(Gift::valid()->show()->orderByDesc('sort')->orderByDesc('id')->get());

        $join_users = GiftLog::where('created_at', '>', Carbon::today()->toDateTimeString())
            ->orderByDesc('id')->pluck('user_id')
            ->unique()->transform(function ($uid) use ($memberTransformer) {
                return $memberTransformer->setTransformer('forSimple')->singleData(Member::find($uid));
            })->values();

        $join_users_count = GiftLog::where('created_at', '>', Carbon::today()->toDateTimeString())->distinct('user_id')->count('user_id');

        //获取真实的领取记录
        $logs = GiftLog::where('created_at', '>', Carbon::today()->toDateTimeString())->orderByDesc('id')->take(3)->get();
        $gift_logs = (new GiftLogTransformer())->listData($logs);

        $lottery_gold = config('car.merchant_config.gold');

        return $this->success(compact('userInfo', 'timesInfo', 'gifts', 'join_users', 'join_users_count', 'gift_logs', 'lottery_gold'));
    }

    //点击抽奖
    public function lottery(MemberRepo $memberRepo, MerchantRepo $merchantRepo)
    {
        //检查用户余额是否足够
        if ($this->user->getCredit() < $this->config['gold'])
            return $this->error(1, '您的余额不足以抽奖');

        //抽奖次数
        $today_lottery_times = GiftLog::where('user_id', $this->user->id)
            ->where('created_at', '>', Carbon::today()->toDateTimeString())
            ->count();
        if ($today_lottery_times >= $this->config['day_limit'])
            return $this->error(1, '今日次数已用完');
        //概率控制
        $rand = mt_rand(0, 100);
        if ($rand > $this->config['lottery_rate'])
            return $this->error(99, '没中奖');

        //随机获取一个合法礼物
        $gift_model = Gift::valid();
        //不获取已经获取过的
        $gift_ids = GiftLog::unused()->where('user_id', $this->user->id)->where('category', '>', 3)
            ->pluck('merchant_gift_id');
        if ($gift_ids) {
            $gift_model = $gift_model->whereNotIn('id', $gift_ids);
        }
        //按库存设置中奖率
        $all_stock = (int)$gift_model->sum('stock');
        if (!$all_stock) {
            return $this->error(1, '礼物已被抢完');
        }
        //根据库存计算概率
//        $lottery_rand = mt_rand(1,$all_stock);
//        $hit_lottery=null;
//
//        $gifts = $gift_model->inRandomOrder()->get();
//
//        foreach ($gifts as $gift) {
//            static $level_left = 0;
//            $level_right = $gift['stock'] + $level_left;
//
//            //dump(compact('all_stock','level_left','level_right','lottery_rand'));
//
//            if($lottery_rand > $level_left && $lottery_rand <= $level_right){
//                $hit_lottery = $gift;
//                break;
//            }
//            $level_left = $level_right;
//        }
//        $lottery = $hit_lottery;

        $all_rand = (int)$gift_model->where('stock','>', 0)->sum('rand');
        $lottery_rand = mt_rand(1, $all_rand);
        $hit_lottery = null;

        $gifts = $gift_model->inRandomOrder()->get();

        foreach ($gifts as $gift) {
            static $level_left = 0;
            $level_right = $gift['rand'] + $level_left;
            if ($lottery_rand > $level_left && $lottery_rand <= $level_right) {
                $hit_lottery = $gift;
                break;
            }
            $level_left = $level_right;
        }
        $lottery = $hit_lottery;

        if (!$lottery) {
            return $this->error(1, '礼物已被抢完');
        }

        DB::beginTransaction();
        //减少库存
        $decreStock = $lottery->decrement('stock');
        //扣减用户余额
        $decreUser = $memberRepo::decrementUserCredit($this->user, $this->config['gold']);
        //添加记录
        $newLog = $merchantRepo->addNewLog($this->user, $lottery);

        //如果是金币或积分，则直接领取
        if ($lottery->category <= 2) {
            $merchantRepo->updateLottery($this->user, $newLog);
        }

        if ($decreStock && $decreUser && $newLog) {
            DB::commit();
            $returnInfo = $this->giftTransformer->setTransformer('forLottery')->singleData($lottery);
            $returnInfo['log_id'] = $newLog->id;
            return $this->success($returnInfo);
        }

        DB::rollback();

        return $this->error(1, '抽奖失败请重试');

    }

    //领取
    public function exchange(MerchantRepo $merchantRepo)
    {
        $this->validate($this->request, [
            'id' => 'required',
        ]);

        $log = GiftLog::unsended()->find($this->request->id);
        if (empty($log)) {
            return $this->error('已经领取过了');
        }

        $gift = Gift::find($log->merchant_gift_id);

        list($code, $message) = $merchantRepo->updateLottery($this->user, $log);

        if ($code === 0) {
            return $this->success($this->giftTransformer->setTransformer('forLottery')->singleData($gift));
        }
        return $this->error('领取失败。' . $message);
    }

    //获取我的记录
    public function mine()
    {
        $gifts = GiftLog::where('user_id', $this->user->id)->with('gift')->orderByDesc('id')->paginate(20);

        $lists = (new GiftLogTransformer())->setTransformer('forMine')->listData($gifts->getCollection());

        return $this->setPage($gifts->hasMorePages())->success($lists);
    }

    //获取真实的领取记录
    public function logs()
    {
        $join_users_count = GiftLog::where('created_at', '>', Carbon::today()->toDateTimeString())->distinct('user_id')->count('user_id');

        $gifts = GiftLog::where('created_at', '>', Carbon::today()->toDateTimeString())->orderByDesc('id')->paginate(20);

        $gift_logs = (new GiftLogTransformer())->listData($gifts->getCollection());

        return $this->setPage($gifts->hasMorePages())->success(compact('join_users_count', 'gift_logs'));
    }

    //填写资料
    public function info()
    {
        $this->validate($this->request, [
            'log_id' => 'required',
            'address' => 'required',
        ]);

        $log = GiftLog::findOrFail($this->request->log_id);
        $log->extra = json_encode([
            'address' => $this->request->address,
            'name' => $this->request->name,
            'phone' => $this->request->phone,
        ]);
        $log->save();
        return $this->success('资料填写成功');

    }
}